package org.custom.spring.boot.datasource.application;

import org.custom.spring.boot.datasource.entity.datasource.CustomDataSourceProperties;
import org.custom.spring.boot.datasource.exception.TipException;
import org.custom.spring.boot.datasource.service.DataSourceBuilder;
import org.custom.spring.boot.datasource.service.DataSourceService;
import org.custom.spring.boot.datasource.service.DynamicDatasourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.custom.spring.boot.datasource.service.DataSourceBuilder.DATA_SOURCE_BUILDERS;

/**
 * 项目启动时对DataSourceBuilder实现类的初始化
 *
 * @author 李坤
 * @date 2022/3/31 15:13
 */
@Component
public class DataSourceRunner implements ApplicationRunner {
    private final Logger logger = LoggerFactory.getLogger(DataSourceRunner.class);

    @Value("${custom.lazy-load-datasource:false}")
    private boolean lazyLoadDatasource;

    @Resource
    private DataSourceService dataSourceService;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private DynamicDatasourceService dynamicDatasourceService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 将 DataSourceBuilder 的实现类按照类型存放
        Optional.ofNullable(applicationContext.getBeansOfType(DataSourceBuilder.class))
                .ifPresent(dataSourceBuilderMap -> dataSourceBuilderMap.forEach((name, dataSourceBuilder) ->
                        DATA_SOURCE_BUILDERS.put(dataSourceBuilder.getSupportDataSource(), dataSourceBuilder)));

        // 初始化数据源
        if (!lazyLoadDatasource) {
            dataSourceService.findAllCustomDataSourceProperties().parallelStream()
                    .collect(Collectors.groupingBy(CustomDataSourceProperties::getOwner))
                    .forEach((owner, customDataSourcePropertiesList) ->
                            customDataSourcePropertiesList.forEach(customDataSourceProperties -> {
                                        try {
                                            dynamicDatasourceService.appendDataSource(customDataSourceProperties);
                                        } catch (TipException exception) {
                                            logger.info(exception.getMessage());
                                        }
                                    }
                            ));
        }
    }
}
